#include <iostream>
#include <cmath>
#include <list>
#include <fstream>
#include <string>
#include <boost/numeric/mtl/mtl.hpp>
#include <cppunit/extensions/HelperMacros.h>
#include <CGAL/Random.h>
#include "../src/fmm.h"
#include "../src/isoline.h"
#include "../src/backtracking.h"
#include "../src/randompoint.h"
#include "../src/sknn.h"
#include "Test_sknn.h" 

CPPUNIT_TEST_SUITE_REGISTRATION (Test_sknn);

void Test_sknn::setUp ()
{
}
void Test_sknn::tearDown()
{

}

void Test_sknn::test_sknn_01()
{
	Mesh mesh;
	bool result = this->read_check_manifold_model (mesh, "../../data/cossphere.obj");
	if (!result) {CPPUNIT_ASSERT_ASSERTION_FAIL("The model is invalid!"); return;}
	
	Random_points_mesh random_mesh(mesh);
	
	Mesh::Point random_point;
	Mesh::FaceHandle fh;
	
	for (int i = 0; i < 100; ++i)
	{
		random_mesh.generate_point(random_point, fh);
		mesh.data(fh).point_set.push_back(std::make_pair(random_point, -1.0));
	}

	
	//2. Set a start POINT. Do FMM.
	int face_idx = 0;
	Mesh::FaceHandle base_face = mesh.face_handle(face_idx);
	Mesh::Point base_point (0,0,0);
	for (Mesh::FaceVertexIter fv_it = mesh.fv_iter(base_face); fv_it; ++fv_it)
	{
		base_point [0] +=mesh.point(fv_it)[0];
		base_point [1] +=mesh.point(fv_it)[1];
		base_point [2] +=mesh.point(fv_it)[2];
	}
	base_point [0] /= 3.0f;
	base_point [1] /= 3.0f;
	base_point [2] /= 3.0f;
	std::vector<Mesh::FaceHandle> vec_base_face_handle;
	vec_base_face_handle.push_back(base_face);

	std::vector<Point_info>  neighbors; 
	sknn(mesh, base_point, base_face, 20, neighbors);

	std::list<std::list<Mesh::Point> >  path_groups; 	

	for (int i = 0; i < neighbors.size(); ++i)
	{
		std::list<Mesh::Point> path;
		Mesh::FaceHandle start_face = neighbors[i].fh;
		Mesh::Point start = neighbors[i].iter->first; 
	    std::vector<Mesh::FaceHandle> face_record;
		Backtracking<double>::draw_geodesics (mesh, start, start_face, base_point, vec_base_face_handle, path, face_record, 0.001);
		path_groups.push_back(path);
	}

	std::ofstream outfile("./georancossphere.obj");
	generate_seperate_group_geodesics(mesh, path_groups, outfile);

	//3. Do one time sknn query

	//Draw 3 geodesics.
	//Begin
	//End
}
